#pragma once

#include "cuda.h"
#include "NVDecode/NvCodec/NvEncoder/NvEncoderCuda.h"
#include "NVDecode/NvCodec/NvDecoder/NvDecoder.h"
#include "NVDecode/Utils/NvCodecUtils.h"
#include "NVDecode/Utils/FFmpegDemuxer.h"
#include "NVDecode/Common/AppDecUtils.h"
#include "NVDecode/Utils/ColorSpace.h"
#include "NVDecode/Utils/NvEncoderCLIOptions.h"

#include <utils/Structs.h>

#include <Poco/Thread.h>

// #include <opencv2/core/cuda.hpp>

class FrameReceiver
{
public:
    FrameReceiver(CameraInfo info = CameraInfo());
    ~FrameReceiver();

    CUcontext cuContext = NULL;
    CUdeviceptr dpFrame = 0;
    CUdeviceptr dMappedFrame = 0;
    cv::cuda::GpuMat dMatFrame;
    float* pixelMap;
    float* uvMap;

    void Start();
    void Stop();

private:
    CameraInfo m_info = CameraInfo();

    int nVideoWidth, nVideoHeight;
    bool bFirstFrame = true;
    bool bReady = false;

    void Init();
    void Dispose();
    bool GetDeviceFrameBuffer(CUdeviceptr *pdpFrame, int *pnPitch);
    int frameNums = 0;

    Poco::Thread _threadReceiveFrame;
    static void threadReceiveFrame(void *pContext);
    void StartReceiveFrame(void);

    uint8_t *pHostFrame = nullptr;
};